const vscode = require('vscode');
const fs = require('fs');
const path = require('path');
const util = require('./util');
const GlobalConfig = require('./view/globalConfig');
const { refreshDevLogin, getCurrentAccount } = require('./refreshLogin');
const prodLogin = require('./prodLogin');
/**
 * 从某个HTML文件读取能被Webview加载的HTML内容
 * @param {*} context 上下文
 * @param {*} templatePath 相对于插件根目录的html文件相对路径
 */
function getWebViewContent(context, templatePath) {
    const resourcePath = util.getExtensionFileAbsolutePath(context, templatePath);
    const dirPath = path.dirname(resourcePath);
    let html = fs.readFileSync(resourcePath, 'utf-8');
    // vscode不支持直接加载本地资源，需要替换成其专有路径格式，这里只是简单的将样式和JS的路径替换
    html = html.replace(/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g, (m, $1, $2) => {
        return $1 + vscode.Uri.file(path.resolve(dirPath, $2)).with({ scheme: 'vscode-resource' }).toString() + '"';
    });
    return html;
}

/**
 * 执行回调函数
 * @param {*} webview 
 * @param {*} message 
 * @param {*} resp 
 */
function invokeCallback(webview, message, resp) {
    console.log('回调消息：', resp);
    // 错误码在400-600之间的，默认弹出错误提示
    if (typeof resp == 'object' && resp.code && resp.code >= 400 && resp.code < 600) {
        util.showError(resp.message || '发生未知错误！');
    }
    webview.postMessage({cmd: 'vscodeCallback', cbid: message.cbid, data: resp});
}

/**
 * 存放所有消息回调函数，根据 message.cmd 来决定调用哪个方法
 */
const messageHandler = {
    // 弹出提示
    alert(global, message) {
        util.showInfo(message.info);
    },
    // 显示错误提示
    error(global, message) {
        util.showError(message.info);
    },
    // 获取工程名
    openUrlInBrowser(global, message) {
        util.openUrlInBrowser(message.url);
        invokeCallback(global.webview, message, {code: 0, text: '成功'});
    },
    refreshLogin (global, message) {
        refreshDevLogin(JSON.parse(message.data));
    },
    prodLogin (global, message) {
        prodLogin(JSON.parse(message.data));
    },
    getCurrentAccount (global, message) {
        const currentAccount = getCurrentAccount();
        invokeCallback(global.webview, message, currentAccount);
    },
    async getConfig(global, message) {
        const config = await GlobalConfig.readConfig(message.key);
        invokeCallback(global.webview, message, config);
    },
    // 保存配置
    async saveConfig(global, message) {
        const result = await GlobalConfig.saveConfig(message.key, message.value);
        invokeCallback(global.webview, message, result);
    }
};

class TestWebviewProvider {
    constructor(context) {
        this.context = context;
        this._view = null;
    }

    resolveWebviewView(webviewView, context, _token) {
        this._view = webviewView;

        webviewView.webview.options = {
            enableScripts: true,
            retainContextWhenHidden: true,
            localResourceRoots: [
                vscode.Uri.file(path.join(this.context.extensionPath, 'lib')),
                vscode.Uri.file(path.join(this.context.extensionPath, 'src'))
            ]
        };

        webviewView.webview.html = getWebViewContent(this.context, 'src/view/test-webview.html');

        // 处理来自WebView的消息
        webviewView.webview.onDidReceiveMessage(message => {
            const global = { 
                webview: webviewView.webview,
                // projectPath: util.getProjectPath()
            };
            
            if (messageHandler[message.cmd]) {
                messageHandler[message.cmd](global, message);
            } else {
                util.showError(`未找到名为 ${message.cmd} 回调方法!`);
            }
        });
    }
}

module.exports = TestWebviewProvider;
